/*=============================================================

PROGRAMMING TECHNIQUES FOR SUPERCOMPUTERS

Assignment Number 6

Task 3

=============================================================*/

#include <stdio.h>
#include <iostream>
#include "timing.hh"
#include <math.h>
#include <fstream>
#include <omp.h>

double timeStamp();
typedef double real;


int main()
{
  double wcTimeStart,wcTimeEnd,cpuTimeStart,cpuTimeEnd,wcTime, cpTime;	
  //int numThreads =0;
         
  std::ofstream fileoutb("plot.dat");
  fileoutb << "# Plot for Task (b)" << std::endl;
  fileoutb << "# N\t MFLOP/sec" << std::endl;

  for (int k =1; k<7; ++k)
  {
      int N = int(pow(10.0,k));
      
      real *a1 = new real[N];
      real *b1 = new real[N];
      real *c1 = new real[N];
      real *d1 = new real[N];
      for (int i = 0; i<N; ++i)
      {	
	b1[i] = i*2.0;
	c1[i] = i*3.0;
	d1[i] = i*1.0;
      }
      long repeat =1;
      real runtime =0.;
      for (; runtime <0.1; repeat*=2)
	{	
	  timing(wcTimeStart,cpuTimeStart);
	  for (int r=0; r<repeat; r++)
	    {
	      {
	      
		#pragma omp parallel for
		for (int i = 0; i<N; i++)
		{
		    a1[i] = b1[i] + c1[i]*d1[i];
		    //numThreads=omp_get_num_threads();
      
		}
	      }
	      if (a1[N-1] <0.) std::cout << "Dummy Loop Encountered"<< std::endl;
	    }
	  timing(wcTimeEnd,cpuTimeEnd);	
	  runtime=wcTimeEnd-wcTimeStart;				
	}
	   repeat/=2;
      long noFlops = N*2*repeat;
      real mFlops = noFlops/runtime/1000000;
      fileoutb << N <<"\t" << mFlops << std::endl;
      delete [] a1;
      delete [] b1;
      delete [] c1;
      delete [] d1;
  }
  
  //std::cout<<"The number of threads is: "<<numThreads<<"\n";
  fileoutb.close();
  return 0;
}

double timeStamp()
{
    struct timeval tp;
    gettimeofday(&tp, NULL);
    return((double)(tp.tv_sec + tp.tv_usec/1000000.0));
}
